// 小程序tab Class
// 全局tab初始化一些配置
const tabConfig = require("./config");
function tabClass(options) {
  const defaultConfig = {
    tabList: [],
    // tab索引
    tabIndex: 0,
    // tab一页数据量
    pageSize: 10,
    // 请求数据函数
    fetchFun: null,
    // 是否预拉去tab list数据
    fetchBefore: true,
    // 搜索关键字
    query: {},
    // 是否与自定义关键字进行合并
    queryOnly: true,
    // tab http query转换设置
    queryTransform: null,
    // 切换tab是否自动刷新
    refreshAuto: true,
    // tab触底加载完毕是否进行再次加载
    pageEndAgain: true,
    // 列表刷新延迟回调时间
    refreshSpeedTime: 350,
    // 二次处理 response  Fun
    responseFilterFun: null,
    // 更新tab item 数据内容 Fun
    updateTabItemFun: null,
  };

  const mergeConfig = Object.assign(defaultConfig, tabConfig, options);
  if (mergeConfig.tabList) {
    mergeConfig.tabList = mergeConfig.tabList.map((tabItem) => {
      return Object.assign(
        {
          list: [],
          page: 1,
          end: false,
          refreshLoading: false,
          bottomLoading: false,
        },
        tabItem
      );
    });
  } else {
    throw Error("Required configuration parameters tabList are missing ");
  }
  Object.assign(this, mergeConfig);
}

Object.assign(tabClass.prototype, {
  // 获取当前列表配置  默认当前索引
  getTab(index) {
    if (typeof index === undefined) {
      index = this.tabIndex;
    }
    return this.tabList[index];
  },
  // 获取当前索引
  getTabIndex() {
    return this.tabIndex;
  },
  // 页码数量变化
  pageSizeChange(size, nextGetData = true) {
    if (size && typeof size === "number") {
      this.pageSize = size;
      if (nextGetData) {
        return this.getData();
      }
    }
  },
  // 获取内容
  getData(otherConfig) {
    const { refreshAuto, tabIndex } = this;
    const defaultConfig = {
      tab_index: tabIndex,
      tab_refresh: refreshAuto,
    };
    if (otherConfig) {
      Object.assign(defaultConfig, otherConfig);
    }
    return this.change(null, defaultConfig);
  },
  // 获取搜索关键字内容
  search(query, queryOnly = false) {
    this.fetchData({
      query,
      queryOnly,
    });
  },
  // 加载指定tab页内容  传页码 page  index
  fetchData(configParams) {
    if (configParams) {
      const globalConfig = {
        type: this.tabList[configParams.index || 0],
        pageSize: this.pageSize,
        query: this.query,
        queryOnly: this.queryOnly,
      };
      const mergeConfig = Object.assign({}, globalConfig, configParams);
      return this.getPageData(mergeConfig);
    }
  },
  // 加载分页内容
  getPageData(params) {
    const { queryTransform } = this;
    const requestData = {};
    // 转换query
    if (queryTransform) {
      Object.keys(queryTransform).forEach((key) => {
        const transKey = queryTransform[key];
        requestData[transKey] = params[key];
      });
    }
    // query关键字合并规则
    // 如果单独查询  取 query  否咋合并全局query
    const { query = {}, queryOnly } = params;
    if (query) {
      let nextquery;
      if (queryOnly) {
        nextquery = query;
      } else {
        nextquery = Object.assign({}, this.query || {}, query);
      }
      Object.assign(requestData, nextquery);
    }
    return new Promise((resolve, reject) => {
      if (this.fetchFun && typeof this.fetchFun === "function") {
        this.fetchFun(requestData)
          .then((res) => {
            // 对 response data进行再处理
            if (
              this.responseFilterFun &&
              typeof this.responseFilterFun === "function"
            ) {
              res = this.responseFilterFun(res);
            }
            resolve(res);
          })
          .catch((err) => {
            reject(err);
          });
      } else {
        reject("config: fetchFun must be required");
      }
    });
  },
  // 获取指定配置参数
  _getOnlyConfig(key, reserveVal) {
    if (key in this) {
      return this[key];
    } else {
      return reserveVal;
    }
  },
  // 切换导航
  change(event, otherEvent, setIndex = true) {
    return new Promise((resolve, reject) => {
      if (!this.tabList || !this.tabList.length) {
        reject("config: list is required , length not be 0");
      }
      let paramsData;
      // 绑定 event 对象
      if (event) {
        paramsData = event.currentTarget.dataset;
        // 绑定自定义事件
      } else if (otherEvent) {
        paramsData = otherEvent;
      } else {
        reject("missing required parameter");
      }
      // tab索引
      let tabIndex = this.tabIndex;
      // query 信息
      let query;
      // 不合并全局 query
      let queryOnly;
      // 切换 tab 索引 是否进行刷新
      let refreshAuto;
      // 合并参数
      if (paramsData) {
        tabIndex = paramsData.tab_index;
        refreshAuto = this._getOnlyConfig.call(
          paramsData,
          "tab_refresh",
          this.refreshAuto
        );
        query = this._getOnlyConfig.call(paramsData, "tab_query", this.query);
        queryOnly = this._getOnlyConfig.call(
          paramsData,
          "tab_query_only",
          this.queryOnly
        );
      }
      if (setIndex) {
        // 设置当前索引
        this.tabIndex = tabIndex;
      }
      // 切换加载  条件
      // 强制刷新开启
      //  或者   没有加载完  并且  数据为0
      let tabItem = this.tabList[this.tabIndex];
      if (refreshAuto || (!tabItem.end && !tabItem.list.length)) {
        let nextTabItemPage = tabItem.page
        if (refreshAuto) {
          nextTabItemPage = 1
        }
        return this.getPageData({
          // 类型
          type: tabItem.type,
          // 页码
          page: nextTabItemPage,
          // 每页数据量
          pageSize: this.pageSize,
          // 查询信息
          query,
          // 是否单独查询
          queryOnly,
        })
          .then((res) => {
            if (
              this.updateTabItemFun &&
              typeof this.updateTabItemFun === "function"
            ) {
              // 处理当前列表数据  是否结束   列表数据赋值
              this.updateTabItemFun({
                tabItem: tabItem,
                tabItemPage: nextTabItemPage,
                response: res,
                concatAuto: false,
              });
            }else{
              throw Error("Required configuration parameters - up are missing")
            }
            
            resolve();
          })
          .catch((err) => {
            reject(err);
          });
      }
    });
  },

  // tabs 下拉刷新
  refresh(refreshConfig) {
    return new Promise((resolve, reject) => {
      refreshConfig = Object.assign(
        {
          // 刷新完成 是否进行一次 提示
          notic: true,
          // 是否主动模拟刷新  通常情况都是有用户手动触发
          force: false,
          // 是否启用全局下拉刷新
          openGlobal: true,
        },
        refreshConfig
      );
      if (refreshConfig.openGlobal && refreshConfig.force) {
        wx.startPullDownRefresh();
      }
      const refreshItem = this.tabList[this.tabIndex];
      // 如果当前tabitem处于下拉刷新中 退出
      if (refreshItem.refreshLoading) {
        return;
      }
      refreshItem.refreshLoading = true;

      function finallyFun(finallyState) {
        setTimeout(() => {
          if (refreshConfig.openGlobal) {
            wx.stopPullDownRefresh();
          }
          refreshItem.refreshLoading = false;

          if (finallyState) {
            resolve();
          } else {
            reject();
          }
        }, this.refreshSpeedTime);
      }
      return this.change(
        null,
        {
          tab_index: this.tabIndex,
          tab_refresh: true,
        },
        false
      )
        .then(() => {
          finallyFun.call(this,true);
        })
        .catch((err) => {
          finallyFun.call(this,false);
        });
    });
  },
  // tabs 触底加载
  reachBottom() {
    return new Promise((resolve, reject) => {
      const tabItem = this.tabList[this.tabIndex];
      // 如果处于触底加载事件中  退出
      if (tabItem.bottomLoading) {
        reject();
        return;
      }
      // 已加载完  触底是否再次进行加载
      /* if (tabItem.end && this.pageEndAgain) {
        const tabItemPage = tabItem.page - 1 || 1;
        tabItem.end = false;
        tabItem.page = tabItemPage;
        
      } */
      if (tabItem.end) {
        reject();
        return;
      } else {
        tabItem.bottomLoading = true;
        const nextTabItemPage = tabItem.page + 1;
        return this.getPageData({
          type: tabItem.type,
          page: nextTabItemPage,
          pageSize: this.pageSize,
        })
          .then((res) => {
            // 处理当前列表数据  是否结束   列表数据赋值
           this.updateTabItemFun({
              tabItem: tabItem,
              tabItemPage: nextTabItemPage,
              response: res,
              concatAuto: true,
            });
            resolve();
          })
          .catch((err) => {
            reject(err);
          })
          .finally(() => {
            tabItem.bottomLoading = false;
            
          });
      }
    });
  },
});

module.exports = tabClass;
